package com.eatme.web.advice;

import com.eatme.web.annotation.IgnoreResponseAdvice;
import com.eatme.web.common.vo.AppResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 *  统一响应
 */
@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 判断是否需要对响应进行处理
     * @param returnType the return type
     * @param converterType the selected converter type
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType,
                            Class<? extends HttpMessageConverter<?>> converterType) {

        // 如果当前方法所在的类标识了 @IgnoreResponseAdvice 注解,不需要处理
        if (returnType.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class))
            return false;

        // 如果当前方法标识了 @IgnoreResponseAdvice 注解,不需要处理
        if (returnType.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class))
            return false;

        // 对响应进行处理,执行beforeBodyWrite 方法
        return true;
    }

    /**
     * 响应返回之前的处理
     * @param body the body to be written
     * @param returnType the return type of the controller method
     * @param selectedContentType the content type selected through content negotiation
     * @param selectedConverterType the converter type selected to write to the response
     * @param request the current request
     * @param response the current response
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 定义最终的返回对象
        AppResponse<Object> commonResponse = AppResponse.ok();
        // 如果 body 是 null, response 不需要设置data
        if (null == body)
            return  commonResponse;
        // 如果 body 已经是 CommonResponse, 不需要再次处理
        else if (body instanceof AppResponse)
            commonResponse = (AppResponse<Object>) body;

        // 否则,把响应对象作为 CommonResponse 的 data 部分
        else
            commonResponse.setData(body);
        return commonResponse;
    }
}
